import React, { useEffect, useState, useMemo } from 'react';
import _ from 'lodash';
import { nanoid } from 'nanoid';
import { Button, Spin, Form, Table, Input, message, Popconfirm } from 'antd';
import DraggableModal from '@/components/DraggableModal';
import { PlusSquareOutlined, MinusCircleOutlined } from '@ant-design/icons';
import DebounceWrapper from '@/components/DebounceWrapper';
import {
  fetchResourceMenuActionItems,
  updateResourceMenuActionItems,
} from '@/services/system/resource';
import configMappings from '@/pages/apis.json';
import styles from './index.less';

const randomLength = 12;
const DebounceButton = DebounceWrapper(Button);

export default ({ visible, options, closeModal }) => {
  const { resourceId, path, title } = options;
  const [form] = Form.useForm();
  const [initialLoadingId, setInitialLoadingId] = useState('');
  const [dataList, setDataList] = useState([]);
  const [actionLoading, setActionLoading] = useState(false);
  const initialConfig = useMemo(() => {
    if (path) {
      return configMappings[path] || [];
    }
    return [];
  }, [path]);

  const tableColumns = [
    {
      title: '序号',
      dataIndex: 'index',
      key: 'index',
      align: 'center',
      width: 60,
      render: (text, data, index) => index + 1,
    },
    {
      title: '操作代码',
      dataIndex: 'componentKey',
      key: 'componentKey',
      width: 160,
      render: (text, data) => (
        <div className={styles.tableItemControl}>
          <Form.Item
            name={`componentKey-${data.id}`}
            initialValue={''}
            rules={[
              {
                required: true,
                validator: (rule, value) => {
                  if (value) {
                    const formValues = form.getFieldsValue();
                    const componentKeyOpts = _.pick(
                      formValues,
                      _.filter(
                        _.keys(formValues),
                        (k) => k !== `componentKey-${data.id}` && /^componentKey/.test(k),
                      ),
                    );
                    if (_.includes(_.values(componentKeyOpts), value)) {
                      return Promise.reject(new Error('操作代码不能重复'));
                    }
                    const componentKeyValues = _.values(componentKeyOpts);
                    const sameValues = _.keys(
                      _.pickBy(_.countBy(componentKeyValues), (v) => v > 1),
                    );
                    const safeItems = _.pickBy(
                      componentKeyOpts,
                      (v) => !!v && _.indexOf(sameValues, v) === -1,
                    );
                    form.setFields(_.map(safeItems, (v, k) => ({ name: k, value: v, errors: [] })));
                    return Promise.resolve();
                  }
                  return Promise.reject(new Error('请输入操作代码'));
                },
              },
            ]}
          >
            <Input
              size="small"
              disabled={!!data.disabled}
              placeholder="请输入操作代码"
              maxLength={24}
            />
          </Form.Item>
        </div>
      ),
    },
    {
      title: '操作名称',
      dataIndex: 'componentName',
      key: 'componentName',
      width: 160,
      render: (text, data) => (
        <div className={styles.tableItemControl}>
          <Form.Item
            name={`componentName-${data.id}`}
            initialValue={''}
            rules={[{ required: true, whitespace: true, message: '请输入操作名称' }]}
          >
            <Input size="small" maxLength={24} placeholder="请输入操作名称" />
          </Form.Item>
        </div>
      ),
    },
    {
      title: '接口地址',
      dataIndex: 'resPath',
      key: 'resPath',
      render: (text, data) => (
        <div className={styles.tableItemControl}>
          <Form.Item name={`resPath-${data.id}`} initialValue={''}>
            <Input size="small" maxLength={48} placeholder="请输入接口服务地址" />
          </Form.Item>
        </div>
      ),
    },
    {
      title: '操作',
      dataIndex: 'delete',
      key: 'delete',
      width: 96,
      align: 'center',
      render: (text, data, index) => (
        <DebounceButton
          danger
          size="small"
          type="link"
          icon={<MinusCircleOutlined />}
          onClick={() => {
            setDataList((prevList) => {
              const nextList = [...prevList];
              nextList.splice(index, 1);
              return nextList;
            });
          }}
        >
          删除
        </DebounceButton>
      ),
    },
  ];

  // 获取菜单下的按钮/接口配置
  const getResourceActionData = async (resourceId) => {
    try {
      const res = await fetchResourceMenuActionItems({ resourceId });
      return _.isArray(res) ? _.filter(res, ({ id }) => !!id) : [];
    } catch (e) {
      return [];
    }
  };

  // 初始化
  useEffect(() => {
    if (visible) {
      const nextInitialLoadingId = nanoid(randomLength);
      setInitialLoadingId(nextInitialLoadingId);
      getResourceActionData(resourceId).then((list) => {
        let validDataFetch;
        setInitialLoadingId((currentId) => {
          if (currentId === nextInitialLoadingId) {
            validDataFetch = true;
            return '';
          }
          return currentId;
        });
        if (validDataFetch) {
          const initialValues = {};
          const initialDataList = [];
          _.forEach(list, ({ id, componentKey, componentName, resPath }) => {
            initialDataList.push({ id });
            initialValues[`resPath-${id}`] = resPath || '';
            initialValues[`componentKey-${id}`] = componentKey || '';
            initialValues[`componentName-${id}`] = componentName || '';
          });
          setDataList(initialDataList);
          form.setFieldsValue(initialValues);
        }
      });
      return;
    }
    setDataList([]);
    setInitialLoadingId('');
  }, [visible]);

  // 添加一行表单
  const handleAddItem = () => {
    setDataList((prevList) => {
      const nextList = [...prevList];
      nextList.push({ id: nanoid(randomLength) });
      return nextList;
    });
  };

  // 取消
  const handleCancel = () => {
    if (!actionLoading) {
      closeModal();
    }
  };
  // 重置
  const handleResetWithInitialConfig = () => {
    const defaultValues = {};
    const defaultDataList = [];
    _.forEach(initialConfig, ({ code, name, api }) => {
      const id = nanoid(randomLength);
      defaultDataList.push({ id });
      defaultValues[`resPath-${id}`] = api || '';
      defaultValues[`componentKey-${id}`] = code || '';
      defaultValues[`componentName-${id}`] = name || '';
    });
    setDataList(defaultDataList);
    form.setFieldsValue(defaultValues);
  };
  // 提交
  const handleConfirm = () => {
    form.validateFields().then((values) => {
      setActionLoading(true);
      const listMappings = {};
      _.forEach(_.keys(values), (k) => {
        const combinationKeys = k.split('-');
        const preKey = _.head(combinationKeys);
        const suffixKey = _.last(combinationKeys);
        if (listMappings[suffixKey]) {
          listMappings[suffixKey][preKey] = values[k];
        } else {
          listMappings[suffixKey] = _.assign(
            { [preKey]: values[k] },
            suffixKey.length !== randomLength ? { id: suffixKey } : {},
          );
        }
      });
      const params = { list: _.values(listMappings), resourceId };
      // console.log('提交', params);
      updateResourceMenuActionItems(params)
        .then(() => {
          closeModal();
          setActionLoading(false);
          message.success('菜单功能配置保存成功');
        })
        .catch(() => {
          setActionLoading(false);
        });
    });
  };

  return (
    <DraggableModal
      visible={visible}
      width={720}
      title={`资源菜单功能配置${title ? '（' + title + '）' : ''}`}
      onCancel={handleCancel}
      footer={[
        <DebounceButton key="cancel" disabled={actionLoading} onClick={closeModal}>
          取消
        </DebounceButton>,
        <Popconfirm
          key="initial"
          okText="确定"
          cancelText="取消"
          placement="topRight"
          title={
            <>
              确认重置将同步为菜单初始化配置，
              <br />
              重置后点击提交后才会更新配置。
            </>
          }
          onConfirm={handleResetWithInitialConfig}
        >
          <DebounceButton ghost type="primary" disabled={actionLoading || _.isEmpty(initialConfig)}>
            重置
          </DebounceButton>
        </Popconfirm>,
        <DebounceButton
          key="confirm"
          type="primary"
          loading={actionLoading}
          disabled={!!initialLoadingId}
          onClick={handleConfirm}
        >
          提交
        </DebounceButton>,
      ]}
    >
      <Spin spinning={!!initialLoadingId} tip={'初始化..'}>
        <Form form={form} name="authentication-action" validateTrigger="onBlur">
          <Table
            size="small"
            rowKey="id"
            bordered={true}
            pagination={false}
            scroll={{ x: 650, y: 576 }}
            columns={tableColumns}
            dataSource={dataList}
            footer={() => (
              <div className={styles.tableFooterContainer}>
                <DebounceButton size="small" type="link" onClick={handleAddItem}>
                  <PlusSquareOutlined />
                  添加
                </DebounceButton>
              </div>
            )}
          />
        </Form>
      </Spin>
    </DraggableModal>
  );
};
